﻿using System.Xml.Linq;
using Google.Protobuf.WellKnownTypes;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.Extensions.Configuration;
using SageKing.Core.Extensions;
using Serilog;
using Serilog.Filters;
using Serilog.Sinks.OpenTelemetry;

namespace SageKing.LogSerilog.Features;

public class SageKingLogSerilogFeature : FeatureBase
{
    public SageKingLogSerilogFeature(IModule module) : base(module)
    {
    }

    /// <summary>
    /// Represents the options for SageKingCaches feature.
    /// </summary>
    public Action<SageKingLogSerilogOptions> SageKingCacheOptions { get; set; } = _ => { };

    /// <inheritdoc />
    public override void Apply(IConfigurationManager configurationManager, IHostEnvironment hostEnvironment)
    {
        var logconfig = new LoggerConfiguration()
           .ReadFrom.Configuration(configurationManager);

        //var getOltp = System.Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT");
        var getTelemetryendpointKey = "OTEL_EXPORTER_OTLP_ENDPOINT";//Aspire 环境变量 
        if (configurationManager.GetSection(getTelemetryendpointKey).Exists())
        {
            var getEnv = configurationManager[getTelemetryendpointKey];
            var getHeaders = configurationManager["OTEL_EXPORTER_OTLP_HEADERS"]?.Split('=');//"x-otlp-api-key=65df1e2c054d0fdbea120539d29e06f1"
            var getprotocol = configurationManager["OTEL_EXPORTER_OTLP_PROTOCOL"];//grpc
            var getservicename= configurationManager["OTEL_SERVICE_NAME"].IsNullOrEmptyToDefault("OTEL_SERVICE_NAME");

            Log.Logger = logconfig
                .WriteTo.OpenTelemetry(
                   endpoint: getEnv,
                   headers: getHeaders.HasItem() && getHeaders.Length > 1 ? new Dictionary<string, string>() { { getHeaders[0], getHeaders[1] } } : null,
                   protocol: getprotocol.Equals("grpc") ? OtlpProtocol.Grpc : OtlpProtocol.HttpProtobuf,
                   resourceAttributes: new Dictionary<string, object>() {
                       ["service.name"] = getservicename
                   }
               )
              .Filter.ByIncludingOnly(logEvent =>
              {
                  // 场景1：排除包含敏感关键词的日志（如健康检查）
                  if (logEvent.Properties.ContainsKey("RequestPath") &&
                      logEvent.Properties["RequestPath"].ToString().Contains("health"))
                  {
                      return false;
                  }

                  // 场景2：只记录某些特定来源的高级别日志
                  //if (Matching.FromSource("MyApp.BusinessService").Invoke(logEvent))
                  //{
                  //    return logEvent.Level >= Serilog.Events.LogEventLevel.Warning;
                  //}

                  // 默认包含其他日志
                  return true;
              })
              .CreateLogger();
        }
        else
        {
            Log.Logger = logconfig
               .CreateLogger();
        }

        Services.Configure(SageKingCacheOptions);

        Services.AddSerilog();

        Log.Information("Init LogSerilog");
    }
}
